import * as THREE from 'three';

import OrbitControls from 'three-orbitcontrols';

export default class Stars {
    private camera: any;
    private scene: any;
    private renderer: any;
    private stats: any;
    private materials: any = new Array<any>();
    private parameters: any;
    private mouseX: number = 0;
    private mouseY: number = 0;
    private windowHalfX: number = window.innerWidth / 2;
    private windowHalfY: number = window.innerHeight / 2;
    private near: number = 1;
    private far: number = 2000;
    private clock: any;
    private timeTochange: number = 0;
    private scaleindex = 0;
    private scalechanges: any = new Array<number>();
    private lastTime: number = 0;
    private movepositions: any = new Array<number>();
    private colors: any = new Array<any>();

    constructor(element: any) {
        this.init(element);
        this.animate();
        this.AddControl();
    }

    private init(element: any) {

        this.colors.push(0xFFE60D, 0xFFEB30, 0xFFED4B, 0xFEF072, 0xFDF188,
                        0xFFFF9C, 0xFFFFA2, 0xFFFFAD, 0xFFFFB7, 0xFFFFC1);

        this.colors = this.revert(this.colors);

        for (let index = 0; index < 10; index++) {
            this.scalechanges.push(1 + index * 0.05);
        }
        this.scalechanges = this.revert(this.scalechanges);

        console.log(this.scalechanges);

        this.clock = new THREE.Clock();

        this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, this.near, this.far);
        this.camera.position.z = -10;
        this.scene = new THREE.Scene();
        // this.scene.fog = new THREE.FogExp2( 0x000000, 0.0008 );

        const geometry = new THREE.SphereBufferGeometry(0.5, 10, 5);
        // var geometry = new THREE.BoxBufferGeometry(0.1,0.1,0.1);
        const textureLoader = new THREE.TextureLoader();
        const sprite1 = textureLoader.load('../sky/stars.png');



        for (let i = 0; i < 1000; i++) {
            const material = new THREE.MeshBasicMaterial({ map: sprite1, transparent: true, color: 0xFCEE71 });
            const cube = new THREE.Mesh(geometry, material);
            this.scene.add(cube);
            cube.rotation.x = Math.random() * 6;
            cube.rotation.y = Math.random() * 6;
            cube.rotation.z = Math.random() * 6;
            cube.position.x = Math.random() * 40 - 20;
            cube.position.y = Math.random() * 40 - 20;
            cube.position.z = Math.random() * 40 - 20;
            this.scene.add(cube);

            const moves = new Array<any>();
            moves.push(cube.position.x / 100, cube.position.y / 100, cube.position.z / 100);
            this.movepositions.push(moves);

            this.materials.push(material);
        }

        //
        this.renderer = new THREE.WebGLRenderer({ alpha: true });
        this.renderer.setPixelRatio(window.devicePixelRatio);
        this.renderer.setSize(window.innerWidth, window.innerHeight);
        element.appendChild(this.renderer.domElement);
        //
        this.stats = new Stats();

        element.appendChild(this.stats.dom);
        //
        window.addEventListener('resize', this.onWindowResize, false);

        this.Addbackground();
    }

    private Addbackground() {
        const r = '../sky/mp_5dim/';
        const urls = [
            r + 'girl.jpg', r + 'girl.jpg', r + 'girl.jpg', r + 'girl.jpg', r + 'girl.jpg', r + 'girl.jpg',
        ];
        const textureCube = new THREE.CubeTextureLoader().load(urls);
        this.scene.background = textureCube;
    }

    private onWindowResize = () => {
        this.camera.aspect = window.innerWidth / window.innerHeight;
        this.camera.updateProjectionMatrix();
        this.renderer.setSize(window.innerWidth, window.innerHeight);
    }
    private animate = () => {
        requestAnimationFrame(this.animate);
        this.render();
        this.stats.update();
    }
    private render = () => {
        const delta = this.clock.getDelta();

        this.timeTochange += delta;
        const time = Date.now() * 0.00005;

        let scalesize = 1;

        if (this.timeTochange > 0.1) {
            if (this.scaleindex === this.scalechanges.length) {
                this.scaleindex = 0;
            }
            scalesize = this.scalechanges[this.scaleindex];

            this.scaleindex += 1;
            this.timeTochange = 0;

            let changelocation = false;
            if ((this.clock.oldTime - this.lastTime) / 1000 > 0.1) {
                changelocation = true;
                this.lastTime = this.clock.oldTime;
            }
            for (let i = 0; i < this.scene.children.length; i++) {
                const object = this.scene.children[i];
                object.scale.set(scalesize, scalesize, scalesize);

                this.materials[i].color.set(this.colors[this.scaleindex]);

                if (this.scaleindex === 0) {
                    this.materials[i].opacity = 0.1;
                } else {
                    this.materials[i].opacity = 1;
                }
                // this.materials[ i ].opacity = this.scaleindex * 0.1;
                if (changelocation) {
                    object.position.x += this.movepositions[i][0];
                    object.position.y += this.movepositions[i][1];
                    object.position.z += this.movepositions[i][2];
                }
            }
        }

        // for ( var i = 0; i < this.materials.length; i ++ ) {
        //     var color = 0xFAE420;
        //     var h = ( 360 * ( color[ 0 ] + time ) % 360 ) / 360;
        //     // this.materials[ i ].color.setHSL( h, color[ 1 ], color[ 2 ] );
        // }
        this.renderer.render(this.scene, this.camera);


    }

    private AddControl() {
        const controls = new OrbitControls(this.camera);

        controls.damping = 0.2;
        controls.minPolarAngle = 1;
        controls.minDistance = this.near;
        controls.maxDistance = this.far;

        // controls.minAzimuthAngle = 80 * Math.PI / 180; // radians
        // controls.maxAzimuthAngle =  -230 * Math.PI / 180; // radians
        controls.target = new THREE.Vector3(0, 0, 0);
        controls.enablePan = true;
    }

    private revert(list: any[]) {

        const newlist = new Array<any>();

        for (let i: number = list.length; i > 0; i--) {
            newlist.push(list[i]);
        }

        for (let i = 1; i < newlist.length; i++) {
            list.push(newlist[i]);
        }

        return list;
    }


}

